package core;

import java.lang.reflect.Method;
import java.sql.*;
import java.util.regex.Pattern;

/**
 * 执行sql语句的会话对象
 */
public class SqlSession {
    private SqlSessionFactory sqlSessionFactory;

    public SqlSession(SqlSessionFactory sqlSessionFactory) {
        this.sqlSessionFactory = sqlSessionFactory;
    }

    /**
     * 执行insert语句，向数据库中插入数据
     * @param sqlId SQL语句的id
     * @param pojo 插入的数据
     * @return
     */
    public int insert(String sqlId,Object pojo){
        int count=0;
        try {
            //JDBC代码，执行insert语句，完成插入操作
            Connection connection=sqlSessionFactory.getTransaction().getConnection();
            String godbatisSql = sqlSessionFactory.getMappedStatements().get(sqlId).getSql();
            String sql=godbatisSql.replaceAll("#\\{[a-zA-Z0-9_$]*}","?");
            PreparedStatement ps = connection.prepareStatement(sql);
            //给？占位符传值
            //难度是什么：
            //第一：你不知道问号有多少个
            //第二：不知道该将pojo对象中的那个属性赋值到哪一个
            int fromIndex=0;
            int index=1;
            while(true){
                int jingIndex = godbatisSql.indexOf("#",fromIndex);
                if (jingIndex<0) {
                    break;
                }
                int youKuoHaoIndex=godbatisSql.indexOf("}",fromIndex);
                String propertyName = godbatisSql.substring(jingIndex + 2, youKuoHaoIndex).trim();
                fromIndex=youKuoHaoIndex+1;
                //有属性名id，怎么获取id的属性值呢？调用getId方法
                String getMethodName="get"+propertyName.toUpperCase().charAt(0)+propertyName.substring(1);
                Method getMethod = pojo.getClass().getDeclaredMethod(getMethodName);
                Object propertyValue = getMethod.invoke(pojo);
                ps.setString(index,propertyValue.toString());
                index++;
            }
            //执行SQL语句
            count = ps.executeUpdate();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return count;
    }

    /**
     * 查询语句返回一个对象，该方法只适合返回一条记录的SQL语句
     * @param sqlID
     * @param param
     * @return
     */
    public Object selectOne(String sqlID,Object param){
        Object obj=null;
        try {
            Connection connection=sqlSessionFactory.getTransaction().getConnection();
            MappedStatement mappedStatement = sqlSessionFactory.getMappedStatements().get(sqlID);
            String godbatisSql = mappedStatement.getSql();
            String sql = godbatisSql.replaceAll("#\\{[a-zA-Z0-9_$]*}", "?");
            PreparedStatement ps = connection.prepareStatement(sql);
            //给占位符传值
            ps.setString(1,param.toString());
            ResultSet rs = ps.executeQuery();
            //要封装的结果类型
            String resultType = mappedStatement.getResultType();
            //从结果集中取数据封装Java对象
            if (rs.next()) {
                Class<?> resultTypeClass = Class.forName(resultType);
                obj = resultTypeClass.newInstance();
                ResultSetMetaData rsmd = rs.getMetaData();
                int columnCount = rsmd.getColumnCount();
                for (int i = 0; i < columnCount; i++) {
                    String propertyName = rsmd.getColumnName(i+1);
                    String setMethodName= "set"+propertyName.toUpperCase().charAt(0)+propertyName.substring(1);
                    Method setMethod = resultTypeClass.getDeclaredMethod(setMethodName,String.class);
                    setMethod.invoke(obj,rs.getString(propertyName));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return obj;
    }

    //局部测试
    public static void main(String[] args) {
        String sql="insert into t_user values(#{id},#{name},#{age})";
        int fromIndex=0;
        int index=1;
        while(true){
            int jingIndex = sql.indexOf("#",fromIndex);
            if (jingIndex<0) {
                break;
            }
            System.out.println(index);
            index++;
            int youKuoHaoIndex=sql.indexOf("}",fromIndex);
            String propertyName = sql.substring(jingIndex + 2, youKuoHaoIndex).trim();
            System.out.println(propertyName);
            fromIndex=youKuoHaoIndex+1;
        }

    }
    /**
     * 提交事务
     */
    public void commit(){
        sqlSessionFactory.getTransaction().commit();
    }

    /**
     * 回滚事务
     */
    public void rollback() {
        sqlSessionFactory.getTransaction().rollback();
    }

    /**
     * 关闭事务
     */
    public void close(){
     sqlSessionFactory.getTransaction().close();
    }
}
